// symbol   基本数据类型（独一无二的值）

const s1_ = Symbol();
console.log(s1_);

//这里传入string 类型 传入其他类型会自动 调用toString方法
//symbol作为属性名

let s5_ = Symbol('Name');
let obj5_ = {
    [s5_]:'break',
    age:18,
    sex:'man'
};
//symbol作为属性名
for (let obj5Key in obj5_) {
    console.log(obj5Key)
}
//以下方法是遍历不出来的
console.log(Object.keys(obj5_)); //["age", "sex"]
//getOwnPropertyNames 返回一个由指定对象的所有自身属性的属性名（包括不可枚举属性但不包括Symbol值作为名称的属性）组成的数组。
console.log(Object.getOwnPropertyNames(obj5_));// ["age", "sex"]
console.log(JSON.stringify(obj5_));  //{"age":18,"sex":"man"}


//以下方法可遍历出来
console.log(Reflect.ownKeys(obj5_)); // ["age", "sex", Symbol(Name)]
console.log(Object.getOwnPropertySymbols(obj5_));    //[Symbol(Name)] 仅仅返回 Symbol
//Reflect
Reflect.set(obj5_,'key2','val2');    //添加数据
console.log(Reflect.has(obj5_,s5_));      //相当于in 操作符
console.log(obj5_)

//Symbol 的两个静态方法
const s6_ = Symbol.for('break');
const s7_ = Symbol.for('break'); //使用此方法 他会先从全局(整个页面、iframe、Service Worker)查找有没有同key的Symbol，如果有则直接赋值没有就新创建
const s8_ = Symbol.for('haha');

// console.log(s6_ === s7_)  //true

// symbol   基本数据类型（独一无二的值）

const s1 = Symbol();
console.log(s1);

//这里传入string 类型 传入其他类型会自动 调用toString方法
//symbol作为属性名
let s5 = Symbol('Name');
let obj5 = {
    [s5]:'break',
    age:18,
    sex:'man'
};
//symbol作为属性名
for (let obj5Key in obj5) {
    console.log(obj5Key)
}
//以下方法是遍历不出来的
console.log(Object.keys(obj5)); //["age", "sex"]
//getOwnPropertyNames 返回一个由指定对象的所有自身属性的属性名（包括不可枚举属性但不包括Symbol值作为名称的属性）组成的数组。
console.log(Object.getOwnPropertyNames(obj5));// ["age", "sex"]
console.log(JSON.stringify(obj5));  //{"age":18,"sex":"man"}


//以下方法可遍历出来
console.log(Reflect.ownKeys(obj5)); // ["age", "sex", Symbol(Name)]
console.log(Object.getOwnPropertySymbols(obj5));    //[Symbol(Name)] 仅仅返回 Symbol
//Reflect
Reflect.set(obj5,'key2','val2');    //添加数据
console.log(Reflect.has(obj5,s5));      //相当于in 操作符
console.log(obj5)

//Symbol 的两个静态方法
const s6 = Symbol.for('break');
const s7 = Symbol.for('break'); //使用此方法 他会先从全局(整个页面、iframe、Service Worker)查找有没有同key的Symbol，如果有则直接赋值没有就新创建
const s8 = Symbol.for('haha');

// console.log(s6 === s7)  //true



// 十一个Symbol的内置方法

const obj1 = {
    // 重写instanceof方法
    [Symbol.hasInstance](otherObj:any){
        console.log(otherObj);
    }
}
console.log( {'a':11} instanceof <any>obj1 );   //false

let arr3 = [1,2];


// @ts-ignore
console.log([].concat(arr3,[3,4]))  //会自动扁平化
// @ts-ignore
arr3[Symbol.isConcatSpreadable] = false;        //他的默认值是undefined 可读写属性
// @ts-ignore
console.log([].concat(arr3,[3,4]))  //不会自动扁平化

//创建衍生对象的构造函数



class A extends Array{
    constructor(...args:any[]) {
        super(...args);
    }

    static get[Symbol.species](){
        return Array;
    }
    public getName(){
        return 'Break';
    }
}

let c = new A(1,2);

let a = c.map((item:number)=>{
    return item + 1;
})
console.log(c instanceof A);    // true
console.log(a instanceof A);    // true


let obj4 = {
    [Symbol.match](str:string){
        return str.length;
    }
}

// 'Break'.match(<RegExp>obj4);
